﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Jayden.Dll.Cards;
using Jayden.Dll.Cards.Poker.Enums;

namespace Jayden.Windows.PokerWatcher
{
	public partial class PokerOddsCalculatorForm : Form
	{

		private CardSet m_Board;
		private CardSet m_Dead;
		private CardSet[] m_Players = new CardSet[10];

		private TextBox[] tbPlayers = new TextBox[10];
		private Label[] lPlayers = new Label[10];

		public PokerOddsCalculatorForm()
		{
			InitializeComponent();

			tbPlayers[0] = tbPlayer1;
			tbPlayers[1] = tbPlayer2;
			tbPlayers[2] = tbPlayer3;
			tbPlayers[3] = tbPlayer4;
			tbPlayers[4] = tbPlayer5;
			tbPlayers[5] = tbPlayer6;
			tbPlayers[6] = tbPlayer7;
			tbPlayers[7] = tbPlayer8;
			tbPlayers[8] = tbPlayer9;
			tbPlayers[9] = tbPlayer10;

			lPlayers[0] = label1;
			lPlayers[1] = label2;
			lPlayers[2] = label3;
			lPlayers[3] = label4;
			lPlayers[4] = label5;
			lPlayers[5] = label6;
			lPlayers[6] = label7;
			lPlayers[7] = label8;
			lPlayers[8] = label9;
			lPlayers[9] = label10;

		}

		private void bCompute_Click(object sender, EventArgs e)
		{
			m_Board = new CardSet(Card.ParseArray(tbBoard.Text));
			m_Dead = new CardSet(Card.ParseArray(tbDead.Text));
			List<CardSet> cards = new List<CardSet>();
			for (int c = 0; c < 10; c++)
				if (!string.IsNullOrWhiteSpace(tbPlayers[c].Text))
				{
					m_Players[c] = new CardSet(Card.ParseArray(tbPlayers[c].Text));
					cards.Add(m_Players[c]);
					m_Dead.Bitset |= m_Players[c].Bitset;
				}
				else
					m_Players[c] = null;

			if (cards.Count > 1)
			{
				int[] wins = new int[cards.Count];
				uint[] results = new uint[cards.Count];
				uint totalHands = 0;

				foreach (ulong commuity in CardBit.Hands(m_Board.Bitset, m_Dead.Bitset, 5))
				{
					totalHands++;
					uint bestResult = 0;
					uint winners = 0;
					for (int c = 0; c < cards.Count; c++)
					{
						uint result = CardBit.Evaluate(cards[c].Bitset | commuity, 7);
						results[c] = result;
						if (bestResult < result)
						{
							bestResult = result;
							winners = 1u << c;
						}
						else if (bestResult == result)
							winners |= (1u << c);
					}
					int index = 0;
					while (winners != 0)
					{
						if ((winners & 1u) == 1)
							wins[index]++;
						winners = winners >> 1;
						index++;
					}
				}

				int playerIndex = 0;
				for (int c = 0; c < 10; c++)
					if (!string.IsNullOrWhiteSpace(tbPlayers[c].Text))
					{
						lPlayers[c].Text = string.Format("will win {0} times on {1} ({2} %)", wins[playerIndex], totalHands, (wins[playerIndex] * 100.0 / totalHands).ToString("0.00"));
						playerIndex++;
					}
					else
						lPlayers[c].Text = string.Empty;

			}
			else
			{
				ulong playerMask = cards[0].Bitset;

				double[] playerWins = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
				double[] opponentWins = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

				long count = 0;

				foreach (ulong opponentMask in CardBit.Hands(0, m_Board.Bitset | playerMask | m_Dead.Bitset, 2))
				{
					foreach (ulong boardMask in CardBit.Hands(m_Board.Bitset, opponentMask | playerMask | m_Dead.Bitset, 5))
					{
						uint playerHandValue = CardBit.Evaluate(boardMask | playerMask, 7);
						uint opponentHandValue = CardBit.Evaluate(boardMask | opponentMask, 7);

						if (playerHandValue > opponentHandValue)
							playerWins[CardBit.HandType(playerHandValue)] += 1;
						else if (playerHandValue < opponentHandValue)
							opponentWins[CardBit.HandType(opponentHandValue)] += 1;
						else
						{
							playerWins[CardBit.HandType(playerHandValue)] += 1;
							opponentWins[CardBit.HandType(opponentHandValue)] += 1;
						}
						count++;
					}
				}

				Array values = Enum.GetValues(typeof(PokerHandType));

				double playerTotalWins = 0;
				double opponentTotalWins = 0;
				foreach (PokerHandType type in values)
				{
					int index = values.Length - 1 - (int)type;
					playerTotalWins += playerWins[index];
					opponentTotalWins += opponentWins[index];
				}

				for (int c = 0; c < 10; c++)
					if (!string.IsNullOrWhiteSpace(tbPlayers[c].Text))
						lPlayers[c].Text = string.Format("will win {0} times on {1} ({2} %)", (ulong)playerTotalWins, count, (playerTotalWins * 100.0 / count).ToString("0.00"));
					else
						lPlayers[c].Text = string.Empty;

			}
		}
	}
}
